package com.dingup.mock.service.impl;

import com.dingup.api.model.mock.home.SubjectNameDataMapInfo;
import com.dingup.mock.bean.base.ArticleOrder;
import com.dingup.mock.dao.listening.TsListeningArticlesMapper;
import com.dingup.mock.dao.reading.TsReadingArticleDAO;
import com.dingup.mock.dao.speaking.TsSpeakingQuestionsMapper;
import com.dingup.mock.dao.writing.TsWritingQuestionsMapper;
import com.dingup.mock.enums.ExamContentTypeEnum;
import com.dingup.mock.service.MockFeignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.dingup.api.Util.StreamUtil.distinctByKey;
import static com.dingup.mock.enums.ExamContentTypeEnum.*;

/**
 * Created by wancheng on 2018/11/10.
 */
@Service
public class MockFeignServiceImpl implements MockFeignService {

    private static final String TYPE_TPO = "TPO";
    private static final String TYPE_REAL_TEST = "realTest";
    private static final String QUESTION = "Question %s";
    private static final String READING_PASSAGE = "Reading Passage %s %s";
    private static final String[] LISTENING_QUESTION = {"conversation 1", "lecture 1", "lecture 2", "conversation 2", "lecture 3", "lecture 4"};
    private static final String[] WRITING_QUESTION = {"Integrated Writing Task", "Independent Writing Task"};
    @Autowired
    TsListeningArticlesMapper tsListeningArticlesMapper;
    @Autowired
    TsReadingArticleDAO tsReadingArticleDAO;
    @Autowired
    TsSpeakingQuestionsMapper tsSpeakingQuestionsMapper;
    @Autowired
    TsWritingQuestionsMapper tsWritingQuestionsMapper;

    @Override
    public LinkedHashMap<String, List<SubjectNameDataMapInfo>> getExamSubjectName(String type) {
        ExamContentTypeEnum examContentTypeEnum = null;
        if (ExamContentTypeEnum.contains(type)) {
            examContentTypeEnum = ExamContentTypeEnum.valueOf(ExamContentTypeEnum.class, type);
        } else {
            return null;
        }
        LinkedHashMap<String, List<SubjectNameDataMapInfo>> res = new LinkedHashMap<>();
        switch (examContentTypeEnum) {
            case LISTENING:
                List<ArticleOrder> listeningArticles = tsListeningArticlesMapper.getTPORealTestSubjectName();
                res = format(listeningArticles, LISTENING);
                break;
            case SPEAKING:
                List<ArticleOrder> speakingQuestions = tsSpeakingQuestionsMapper.getTPORealTestSubjectName();
                res = format(speakingQuestions, SPEAKING);
                break;
            case READING:
                List<ArticleOrder> readingArticles = tsReadingArticleDAO.getTPORealTestSubjectName();
                res = format(readingArticles, READING);
                break;
            case WRITING:
                List<ArticleOrder> writingQuestions = tsWritingQuestionsMapper.getTPORealTestSubjectName();
                res = format(writingQuestions, WRITING);
                break;
            case ALL:
                List<ArticleOrder> all = tsListeningArticlesMapper.getAllTPORealTestSubjectName();
                res = format(all, ALL);
                break;
            default:
                break;
        }
        return res;
    }

    private LinkedHashMap<String, List<SubjectNameDataMapInfo>> format(List<ArticleOrder> listArticles, ExamContentTypeEnum type) {
        //有序map
        LinkedHashMap<String, List<SubjectNameDataMapInfo>> res = new LinkedHashMap<>();
        //听力数据 按类型分组
        Map<String, List<ArticleOrder>> listMap = listArticles.stream().collect(Collectors.groupingBy(ArticleOrder::getType));
        //有序的集合
        List<ArticleOrder> articles = new ArrayList<>();
        //对听力数据分组进行排序
        articles.addAll(listMap.get(TYPE_TPO).stream().sorted((o1, o2) -> o1.getOrder().compareTo(o2.getOrder())).collect(Collectors.toList()));
        articles.addAll(listMap.get(TYPE_REAL_TEST).stream().sorted((o1, o2) -> o1.getOrder().compareTo(o2.getOrder())).collect(Collectors.toList()));
        //获取去重复的标题
        List<String> listeningSubjectNames = articles.stream().filter(distinctByKey(ArticleOrder::getSubjectName)).map(ArticleOrder::getSubjectName).collect(Collectors.toList());
        //对听力数据 按标题进行分组
        Map<String, List<ArticleOrder>> articlesMap = articles.
                stream().collect(Collectors.groupingBy(ArticleOrder::getSubjectName));
        //有序的集合
        for (String subjectName : listeningSubjectNames) {
            List<SubjectNameDataMapInfo> subjectNameDataMapInfos = null;
            switch (type) {
                case LISTENING:
                    subjectNameDataMapInfos = articlesMap.get(subjectName)
                            .stream()
                            .map(l -> new SubjectNameDataMapInfo(l.getId(), LISTENING_QUESTION[l.getArticleNum() - 1], l.getArticleNum()))
                            .collect(Collectors.toList());
                    break;
                case SPEAKING:
                    subjectNameDataMapInfos = articlesMap.get(subjectName)
                            .stream()
                            .map(l -> new SubjectNameDataMapInfo(l.getId(), String.format(QUESTION, l.getArticleNum()), l.getArticleNum()))
                            .collect(Collectors.toList());
                    break;
                case READING:
                    subjectNameDataMapInfos = articlesMap.get(subjectName)
                            .stream()
                            .map(l -> new SubjectNameDataMapInfo(l.getId(), String.format(READING_PASSAGE, l.getArticleTitle(), l.getArticleNum()), l.getArticleNum()))
                            .collect(Collectors.toList());
                    break;
                case WRITING:
                    subjectNameDataMapInfos = articlesMap.get(subjectName)
                            .stream()
                            .map(l ->
                                    new SubjectNameDataMapInfo(l.getId(), WRITING_QUESTION[l.getArticleNum() - 1], l.getArticleNum()))
                            .collect(Collectors.toList());
                    break;
                case ALL:
                    subjectNameDataMapInfos = new ArrayList<>();
                    break;
                default:
                    break;
            }
            res.put(subjectName, subjectNameDataMapInfos);
        }
        return res;
    }

}
